/**
 * 自定义简单版开始时间~结束时间选择组件,可以设定日期范围，也可以设定月份范围
 * by zhangxinyue
 * create 2019-09-23
 * modify 2019-12-04
 */
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { DatePicker, Form } from 'antd';
import moment from 'moment';
import styles from './style.less';

const { MonthPicker } = DatePicker;
const rootStyle = { display: 'flex', justifyContent: 'center', alignItems: 'flex-start' };
const sepStyle = { width: '10%', display: 'flex', alignItems: 'center', lineHeight: '1.5', justifyContent: 'center', fontSize: '18px' };

class SimpleRangeDateC extends Component {
  // props默认值
  static defaultProps = {
    startOnChange: () => {}, // 开始时间内容变化时的回调，默认不执行回调
    endOnChange: () => {}, // 结束时间内容变化时的回调，默认不执行回调
    disableStart: '', // 开始时间禁用范围限制，默认为空，不纳入禁用计算范围,若传null，则所有时间禁用
    disableEnd: '', // 结束时间禁用范围限制，默认为空，不纳入禁用计算范围，若传null，则所有时间禁用
    dataType: 'date', // 默认是年月日类型
    startInitial: null, // 开始时间初始默认值（未设置）
    endInitial: null, // 结束时间初始默认值（未设置）
    onRef: () => {}, // 本组件的引用
    allowClear: false, // 默认false
    style: {}, // 样式
    disabled: false, // 默认启用
    disableFuture: true, // 默认禁用今天往后的日期
    colon: false,
  };

  constructor(props) {
    super(props);
    const { startInitial, endInitial } = props;

    // 初始化state状态(当从父组件传入的为''时，转为null，DatePicker无法识别'')
    this.state = {
      startValue: startInitial === '' || startInitial === undefined ? null : startInitial, // 开始时间
      endValue: endInitial === '' || endInitial === undefined ? null : endInitial, // 结束时间
    };

    // 记录初始化值，因为从外界调用form的resetFields方法时，仅能将开始时间和结束时间的展示内容初始化，不能将禁选范围初始化
    this.start = startInitial === '' || startInitial === undefined ? null : startInitial;
    this.end = endInitial === '' || endInitial === undefined ? null : endInitial;
  }

  componentDidMount() {
    // 父组件对本组件的引用
    this.props.onRef(this);
  }

  componentDidUpdate(prevProps) {
    let { startInitial, endInitial } = prevProps;
    startInitial = startInitial ? startInitial.format('YYYYMMDD') : '--'; // 开始时间
    endInitial = endInitial ? endInitial.format('YYYYMMDD') : '--'; // 结束时间

    let { startInitial: startInitialN, endInitial: endInitialN } = this.props;
    startInitialN = startInitialN ? startInitialN.format('YYYYMMDD') : '--'; // 开始时间
    endInitialN = endInitialN ? endInitialN.format('YYYYMMDD') : '--'; // 结束时间

    // 前后两次props值一样，则返回
    if (startInitial === startInitialN && endInitial === endInitialN) return;
    this.setState({
      startValue: this.props.startInitial,
      endValue: this.props.endInitial,
    });
    this.start = this.props.startInitial;
    this.end = this.props.endInitial;
  }

  // 定义开始时间变化时事件
  onStartChange = (value) => {
    this.setState({
      startValue: value,
    });

    this.props.startOnChange && this.props.startOnChange(value); // 发送开始时间变更事件
  };

  // 定义结束时间变化时事件
  onEndChange = (value) => {
    this.setState({
      endValue: value,
    });

    this.props.endOnChange && this.props.endOnChange(value); // 发送结束时间变更事件
  };

  // 非初始化状态下更改开始时间和结束时间（供父组件调用）
  setDate = (start, end) => {
    const startF = {};
    startF[this.props.startIndex] = start === '' || start === undefined ? null : start;
    this.props.form?.setFieldsValue(startF);

    const endF = {};
    endF[this.props.endIndex] = end === '' || end === undefined ? null : end;
    this.props.form?.setFieldsValue(endF);

    this.setState({
      startValue: start === '' || start === undefined ? null : start,
      endValue: end === '' || end === undefined ? null : end,
    });
  };

  // 外界调用了form的resetFields方法，需同时调用该方法
  reset = () => {
    this.setDate(this.start, this.end);
  };

  // 定义开始时间禁选范围
  disabledStartDate = (date) => {
    const { disableStart } = this.props; // 开始禁用时间

    // 当有数据的起始时间为null（无开始时间,禁用所有开始时间）
    if (disableStart === null) return true;

    const { endValue } = this.state; // 结束时间
    const { disableFuture } = this.props; // 是否禁用今天以后的日期

    // 当用户未设置无数据的起始时间，则该条件不做为禁用时间依据
    if (disableStart === '') {
      if (endValue === null) {
        // 当结束时间未设定时
        if (disableFuture) {
          // 当需要禁用从今天往后的时间时
          return date.format('YYYYMMDD') > moment().format('YYYYMMDD'); // 开始时间不能晚于当前时间
        } else {
          return false;
        }
      } // 当设置了结束时间
      return date.format('YYYYMMDD') > endValue.format('YYYYMMDD'); // 开始时间不能晚于结束时间
    }
    // 当用户设置了无数据的起始时间
    if (endValue === null) {
      // 当结束时间未设定时
      if (disableFuture) {
        return date.format('YYYYMMDD') > moment().format('YYYYMMDD') || date.format('YYYYMMDD') < disableStart.format('YYYYMMDD');
      } else {
        return date.format('YYYYMMDD') < disableStart.format('YYYYMMDD');
      }
    }
    // 当设置了结束时间
    return date.format('YYYYMMDD') > endValue.format('YYYYMMDD') || date.format('YYYYMMDD') < disableStart.format('YYYYMMDD');
  };

  // 定义结束时间禁选范围
  disabledEndDate = (date) => {
    const { disableEnd } = this.props; // 结束禁用时间

    // 当有数据的结束时间为null（无结束时间，禁用所有结束时间）
    if (disableEnd === null) return true;

    const { startValue } = this.state; // 开始时间
    const { disableFuture } = this.props; // 是否禁用今天以后的日期

    // 当用户未设置无数据的结束时间，则该条件不做为禁用时间依据
    if (disableEnd === '') {
      // 当开始时间未设定时
      if (startValue === null) {
        if (disableFuture) {
          return date.format('YYYYMMDD') > moment().format('YYYYMMDD'); // 结束时间不能晚于当前时间
        } else {
          return false;
        }
      }
      // 当设置了开始时间
      if (disableFuture) {
        // 结束时间不能早于开始时间，不能晚于当前时间
        return date.format('YYYYMMDD') < startValue.format('YYYYMMDD') || date.format('YYYYMMDD') > moment().format('YYYYMMDD');
      } else {
        return date.format('YYYYMMDD') < startValue.format('YYYYMMDD');
      }
    }
    // 当用户设置了无数据的结束时间
    if (startValue === null) {
      // 当开始时间未设定时
      return date.format('YYYYMMDD') > disableEnd.format('YYYYMMDD'); // 结束时间不能晚于无数据的结束时间
    }
    // 当设置了开始时间
    return date.format('YYYYMMDD') < startValue.format('YYYYMMDD') || date.format('YYYYMMDD') > disableEnd.format('YYYYMMDD');
  };

  render() {
    const { disabledEndForm, dataType, form, startIndex, endIndex, style, allowClear, disabled, rules, startInitial, endInitial, colon } = this.props;
    return (
      <div className={styles.simpleRangeDate} style={{ ...rootStyle, ...style }}>
        {/* 开始时间 */}
        <Form.Item
          name={startIndex}
          initialValue={startInitial === '' || startInitial === undefined ? null : startInitial}
          rules={rules?.beginDate ? rules.beginDate : []}
          style={{ width: '45%' }}
          colon={colon}
        >
          {dataType === 'date' ? (
            <DatePicker
              placeholder='开始日期'
              allowClear={allowClear}
              style={{ width: '100%' }}
              disabledDate={this.disabledStartDate} // 不可选择的日期
              onChange={this.onStartChange} // 时间发生变化的回调
              disabled={disabled}
            />
          ) : (
            <MonthPicker
              placeholder='开始月份'
              allowClear={allowClear}
              style={{ width: '100%' }}
              disabledDate={this.disabledStartDate} // 不可选择的日期
              onChange={this.onStartChange} // 时间发生变化的回调
              disabled={disabled}
            />
          )}
          {/* )} */}
        </Form.Item>
        <div style={sepStyle}>~</div>
        {/* 结束时间 */}
        <Form.Item
          name={endIndex}
          initialValue={endInitial === '' || endInitial === undefined ? null : endInitial}
          rules={rules?.endDate ? rules.endDate : []}
          style={{ width: '45%' }}
        >
          {dataType === 'date' ? (
            <DatePicker
              placeholder='结束日期'
              allowClear={allowClear}
              style={{ width: '100%' }}
              disabledDate={this.disabledEndDate} // 不可选择的日期
              onChange={this.onEndChange} // 时间发生变化的回调
              disabled={disabled || disabledEndForm}
            />
          ) : (
            <MonthPicker
              placeholder='结束月份'
              allowClear={allowClear}
              style={{ width: '100%' }}
              disabledDate={this.disabledEndDate} // 不可选择的日期
              onChange={this.onEndChange} // 时间发生变化的回调
              disabled={disabled || disabledEndForm}
            />
          )}
        </Form.Item>
      </div>
    );
  }
}

// props类型
SimpleRangeDateC.propsTypes = {
  form: PropTypes.object, // form对象
  startIndex: PropTypes.string, // Form识别的开始时间Item ID
  endIndex: PropTypes.string, // Form识别的结束时间Item ID
  startInitial: PropTypes.object, // 开始时间初始默认值
  endInitial: PropTypes.object, // 结束时间初始默认值
  disableStart: PropTypes.object, // 设置当前的开始时间不能早于该值，为''时，不将该值用于计算开始时间的禁用范围
  disableEnd: PropTypes.object, // 设置当前的结束时间不能晚于该值，为''时，不将该值用于计算结束时间的禁用范围
  startOnChange: PropTypes.func, // 开始时间变化时的回调
  endOnChange: PropTypes.func, // 结束时间变化时的回调
  dataType: PropTypes.string, // 日期控件类型（年月日类型：date，年月类型：month）
  style: PropTypes.object, // 样式
  allowClear: PropTypes.bool, // 允许清空
  onRef: PropTypes.func, // 本组件的引用（可用来父组件调用内部方法）
  disabled: PropTypes.bool, // 是否禁用
  rules: PropTypes.object, // 校验规则
  disableFuture: PropTypes.bool, // 是否禁用今天往后的日期
  colon: PropTypes.bool, // 是否显示冒号
};

export default SimpleRangeDateC;
